﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition.Hosting;


namespace WebFabricator.org
{
    //http://randomactsofcoding.blogspot.com/2010/01/configurable-type-catalog-for-mef.html
    /// <summary>
    /// Aggregates information from the configuration file and queries to the Fabric to resolve MEF compositon requests
    /// </summary>
    [Namespace(typeof(WebFabricatorCatalog<>))]
    public class WebFabricatorCatalog<T> : TypeCatalog, IEnumerable<Type>
    {
        public WebFabricatorCatalog(IWebFabric<T> fabric)
            : base(GetTypes(fabric))
        {

        }

        private static IEnumerable<Type> GetTypes(IWebFabric<T> fabric)
        {
            var globals = Application.Adorners.ToArray();
            var result = fabric.GetValue(typeof(WebFabricatorCatalog<>).GetNamespace().ToString());

            if (result != null && result.RawValue is IEnumerable<string>)
            {
                var locals = result.RawValue as IEnumerable<string>;
                return locals.Select(type => Type.GetType(type))
                    .Where(type => type != null)
                    .Concat(globals)
                    .ToArray();
            }

            return globals.ToArray();
        }

        public IEnumerator<Type> GetEnumerator()
        {
            var method = Type.GetType("System.ComponentModel.Composition.ReflectionModel.ReflectionComposablePartDefinition, System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089").GetMethod("GetPartType");
            foreach(var part in Parts) 
                yield return method.Invoke(part, new object[] { }) as Type;
            
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
